/* main.c
 * This file is part of the Tisa Project.
 *  
 * Authors: Cleiber Marques da Silva <cleiber.dev@gmail.com>
 *          Odilson Tadeu Valle <odilson@sj.cefetsc.edu.br>
 *
 * Tisa Project is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; version 2 of
 * the License.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>

#include "tisa.h"
#include "log.h"
#include "tqueue.h"
#include "socket.h"

pthread_t runner_alarms;

static void conf_usage(void)
{
	fprintf(stderr,
			"Usage: tisa [OPTION]...\nOptions:\n"
			"-a\tAddress IP or name of server\n"
			"-f\tFile for logs\n"
			"-h\tDisplay this help and exit\n"
			"-p\tPort of server\n");
}

static int conf_cmdline(struct tisa_config *cfg, int argc, char **argv)
{
	int c;

	while ((c = getopt(argc, argv, "afhp")) != -1) {
		switch(c) {
		case 'a':
			cfg->address = optarg;
			break;
		case 'f':
			cfg->path = optarg;
			break;
		case 'h':
			conf_usage();
			return -1;
		case 'p':
			cfg->port = atoi(optarg);
			break;
		default:
			fprintf(stderr, "arg %s failed!\n", optarg);
			conf_usage();
			return -1;
		}
	}
	return 0;
}

static void *handler_alarms(void *arg)
{
	struct boiler *heater = (struct boiler *) arg;
	log_print(LOG_NOTICE, "thread handler_alarms started\n");
	for (;;) {

		if(heater->flag & 4)
			break;

		pthread_cond_wait(&heater->cond, &heater->mutex);

		if (heater->flag & 1) {
			log_print(LOG_WARNING, "Warning temperature\n");
			fprintf(stderr, "Warning temperature\n");
		} else if (heater->flag & 2) {
			log_print(LOG_WARNING, "Warning level\n");
			fprintf(stderr, "Warning level\n");
		}
	}
	pthread_exit(NULL);
}

int main(int argc, char **argv)
{
	int i, ret;
	struct boiler *heater;
	struct tisa_config *cfg;
	pthread_t alarms;

	if (!(cfg = malloc(sizeof(struct tisa_config)))) {
		fprintf(stderr, "malloc tisa_config failed!\n");
		exit(1);
	}
	/* Set values default */
	cfg->address = ADDRESS;
	cfg->path = PATH;
	cfg->port = PORT;

	if((conf_cmdline(cfg, argc, argv)) < 0) {
		ret = 1;
		goto cfg_failed;
	}
	
	if (!(heater = malloc(sizeof(struct boiler)))) {
		fprintf(stderr, "malloc boiler failed\n");
		ret = 1;
		goto cfg_failed;
	}
	
	memset(heater, 0, sizeof(struct boiler));

	if ((heater->sock_fd = socket_init()) < 0) {
		fprintf(stderr, "socket_init failed!\n");
		ret = 1;
		goto heater_failed;
	}

	if ((create_destination(cfg->address, cfg->port, &heater->server)) < 0) {
		fprintf(stderr, "create_destination failed!\n");
		ret = 1;
		goto heater_failed;
	}

	/* Set values default */
	heater->variables[TREF] = 25;
	heater->variables[HREF] = 2;

	if (pthread_mutex_init(&heater->mutex, NULL) ||
	    pthread_cond_init(&heater->cond, NULL)) {
		ret = 1;
		goto heater_failed;
	} 

	if ((log_init(cfg->path)) < 0) {
		fprintf(stderr, "log_init failed\n");
		ret = 1;
		goto heater_failed;
	}

	for (i = 0; i < MAX_SCHED_TASK; i++)
		INIT_LIST_HEAD(&heater->tqe[i].list);

	if (taskqueue_init() < 0) {
		fprintf(stderr, "taskqueue_init failed!\n");
		ret = 1;
		goto heater_failed;
	}
	
	add_task(TS_TEMP, &heater->tqe[0], control_temp);
	add_task(TS_LEVEL, &heater->tqe[1], control_level);
	add_task(TS_SCREEN, &heater->tqe[2], refresh_screen);

	/* Thread handler_alarms */
	if (pthread_create(&alarms, NULL, handler_alarms, heater)) {
		fprintf(stderr, "handle_alarms failed!");
		ret = 1;
		goto heater_failed;
	}

	terminal(heater);

	taskqueue_destroy();
	log_close();
	
	/* End thread handler_alarms */
	heater->flag |= 4;
	pthread_cond_signal(&heater->cond);
	pthread_join(alarms, NULL);
	ret = 0;

heater_failed:
	free(heater);
cfg_failed:
	free(cfg);
	exit(ret);
}
